﻿/** 
 * Copyright 2010 NUMKIT.COM (contact: opensource@numkit.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 * @author 陈超
 * @version 1.0
 */
import flash.external.ExternalInterface;
class Line {
	public static var lineTextColor:Number = 0xFFFFFF;
	private static var formatter:TextFormat;
	private static var tipTF:TextField;
	private var id:String;
	private var color:Number;
	private var flashColor:Number;
	private var isFlashing:Boolean = false;
	private var name:String = "";
	private var nodeA:Node;
	private var nodeB:Node;
	private var mc:MovieClip;
	private var subMC:MovieClip;
	private var fontSize:Object;
	public function Line(node:XMLNode, aNode:Array) {
		if (formatter == undefined) {
			formatter = new TextFormat();
			formatter.size = 12;
			formatter.color = lineTextColor;
		}
		if (node.nodeName != "line") {
			throw new Error("Not a line node!");
		}
		this.id = node.attributes["id"];
		for (var child:XMLNode = node.firstChild; child != null; child=child.nextSibling) {
			var nodeName:String = child.nodeName;
			if (nodeName == "color") {
				color = Number(child.firstChild.nodeValue);
			} else if (nodeName == "flash") {
				flashColor = Number(child.attributes["color"]);
				isFlashing = child.firstChild.nodeValue == "0" ? false : true;
			} else if (nodeName == "name") {
				name = child.firstChild.nodeValue;
			} else if (nodeName == "nodeA") {
				var nodeIDA = child.firstChild.nodeValue;
				for (var i:Number = 0; i<aNode.length; i++) {
					if (aNode[i].getID() == nodeIDA) {
						nodeA = aNode[i];
					}
				}
			} else if (nodeName == "nodeB") {
				var nodeIDB = child.firstChild.nodeValue;
				for (var i:Number = 0; i<aNode.length; i++) {
					if (aNode[i].getID() == nodeIDB) {
						nodeB = aNode[i];
					}
				}
			}
		}
		if (id == undefined) {
			throw new Error("line node id attribute Not Set!");
		}
		if (color == undefined || isNaN(color)) {
			throw new Error("color node not found or err!");
		}
		if (flashColor == undefined || isNaN(flashColor)) {
			throw new Error("color attribute in flash node not found or err!");
		}
		if (isFlashing == undefined) {
			throw new Error("flash node not found!");
		}
		if (name == undefined) {
			throw new Error("name node not found!");
		}
		if (nodeA == undefined) {
			throw new Error("nodeA node not found!");
		}
		if (nodeB == undefined) {
			throw new Error("nodeB node not found!");
		}
		fontSize = formatter.getTextExtent(this.name);
	}
	public function repaint():Void {
		mc.clear();
		subMC.clear();
		subMC.removeMovieClip();
		var a:Point = nodeA.getEndPos(this);
		var b:Point = nodeB.getEndPos(this);
		if (a == undefined || b == undefined) {
			throw new Error("Get line ends position failed!");
		}
		mc.lineStyle(2, color, 100, true, "normal", "square", "miter", 0);
		mc.moveTo(a.x, a.y);
		mc.lineTo(b.x, b.y);
		if (isFlashing) {
			subMC = mc.createEmptyMovieClip("subMC", mc.getNextHighestDepth());
			subMC.lineStyle(3, flashColor, 100, true, "normal", "square", "miter", 0);
			subMC.moveTo(a.x, a.y);
			subMC.lineTo(b.x, b.y);
			var count:Number = 0;
			subMC.count = count;
			subMC.onEnterFrame = function():Void  {
				count++;
				if (count == 6) {
					this._alpha = (this._alpha == 100 ? 0 : 100);
					this.updateAfterEvent();
					count = 0;
				}
			};
		}
	}
	public function draw(mc:MovieClip):Void {
		this.mc = mc;
		var a:Point = nodeA.getEndPos(this);
		var b:Point = nodeB.getEndPos(this);
		if (a == undefined || b == undefined) {
			throw new Error("Get line ends position failed!");
		}
		mc.lineStyle(2, color, 100, true, "normal", "square", "miter", 0);
		mc.moveTo(a.x, a.y);
		mc.lineTo(b.x, b.y);
		if (isFlashing) {
			subMC = mc.createEmptyMovieClip("subMC", mc.getNextHighestDepth());
			subMC.lineStyle(3, flashColor, 100, true, "normal", "square", "miter", 0);
			subMC.moveTo(a.x, a.y);
			subMC.lineTo(b.x, b.y);
			var count:Number = 0;
			subMC.count = count;
			subMC.onEnterFrame = function():Void  {
				count++;
				if (count == 6) {
					this._alpha = (this._alpha == 100 ? 0 : 100);
					this.updateAfterEvent();
					count = 0;
				}
			};
		}
		//添加事件处理    
		var line:Line = this;
		mc.line = line;
		mc.fontSize = fontSize;
		mc.tipTF = tipTF;
		mc.formatter = formatter;
		mc.onRelease = function():Void  {
			var id:String = line.getID();
			var name:String = line.getName();
			ExternalInterface.call(Constants.LineClickCallBack, Constants.FlashObjID, id, name);
		};
		mc.onRollOver = function():Void  {
			var name:String = line.getName();
			if (name != undefined && name != "") {
				tipTF.text = name;
				tipTF.setTextFormat(formatter);
				tipTF._width = fontSize.textFieldWidth;
				tipTF._visible = true;
			}
		};
		mc.onRollOut = function():Void  {
			tipTF.text = "";
			tipTF._visible = false;
		};
	}
	public static function setTipTF(theTipTF:TextField):Void {
		tipTF = theTipTF;
	}
	public function getName():String {
		return name;
	}
	public function getColor():Number {
		return color;
	}
	public function getFlashColor():Number {
		return flashColor;
	}
	public function isFlash():Boolean {
		return isFlashing;
	}
	public function getNodeA():Node {
		return nodeA;
	}
	public function getNodeB():Node {
		return nodeB;
	}
	public function getMC():MovieClip {
		return mc;
	}
	public function getID():String {
		return id;
	}
	public function hasSameEndsWith(line:Line):Boolean {
		if (this.getNodeA() == line.getNodeA() && this.getNodeB() == line.getNodeB()) {
			return true;
		}
		if (this.getNodeA() == line.getNodeB() && this.getNodeB() == line.getNodeA()) {
			return true;
		}
		return false;
	}
	public function getTheOtherEnd(one:Node):Node {
		if (this.getNodeA() == one) {
			return this.getNodeB();
		}
		if (this.getNodeB() == one) {
			return this.getNodeA();
		}
		return undefined;
	}
}
